package com.fancon.android.emoji;

import java.io.IOException;
import java.util.ArrayList;

import com.fancon.android.emoji.EmojiUtil.EmojiMap;



import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.util.Log;

/**
 * Used to get ImageDrawable from source string
 * 
 * @author Wazi Armstrong
 * 
 */
public class EmojiDrawableGetter implements Html.ImageGetter {
	private static final String TAG = "EmojiImageGetter";
	private AssetManager mManager;
	private EmojiUtil mEmojiUtil;
	private Drawable mNoImage;
	public static final String NO_IMAGE ="noimage.png";
	private Context mContext;
	EmojiDrawableGetter(AssetManager manager, EmojiUtil emojiUtil) {
		this.mManager = manager;
		this.mEmojiUtil = emojiUtil;
		try {
			mNoImage = Drawable.createFromStream(mManager.open(mEmojiUtil.getBaseFolder() + "/noimage.png"), null);
			mNoImage.setBounds(0, 0, (int) (mNoImage.getIntrinsicWidth()), (int) (mNoImage.getIntrinsicHeight()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/*
	 * Overrite getDrawable for extract image source from html
	 * public static EmojiImageGetter getInstance(AssetManager manager,
	 * EmojiUtil emojiUtil) { if(sImageGetter == null) sImageGetter = new
	 * EmojiImageGetter(manager, emojiUtil); return sImageGetter; }
	 */
	public Drawable getDrawable1(String code) {
		for (ArrayList<EmojiMap> map : mEmojiUtil.getEmojiMaps()) {
			for (EmojiMap emojiMaps : map) {
				if (code.equals(emojiMaps.code)) {
					if (emojiMaps.image == null || emojiMaps.image.equals(NO_IMAGE)) return mNoImage;
					try {
						Drawable image = Drawable
								.createFromStream(
										mManager.open(mEmojiUtil.getBaseFolder() + "/"
												+ EmojiUtil.EMOJI_CATEGORIES[emojiMaps.category] + "/"
												+ emojiMaps.image), null);
						image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
						return image;
					} catch (IOException e) {
						e.printStackTrace();
						return mNoImage;
					}
				}
			}
		}
		Log.d(TAG, "CODE: " + code);
		return mNoImage;
	}
	/**
	 * Overrite getDrawable for extract image source from html
	 * change from get drawable at assets to get drawable from resource
	 * @author chutieucodon
	 */
	@Override
	public Drawable getDrawable(String code) {
		// TODO Auto-generated method stub
		for (ArrayList<EmojiMap> map : mEmojiUtil.getEmojiMaps()) {
			for (EmojiMap emojiMaps : map) {
				if (code.equals(emojiMaps.code)) {
					if (emojiMaps.image == null || emojiMaps.image.equals(NO_IMAGE)) return mNoImage;
					try {
						Drawable image = null;
						if(mContext == null){
							image = Drawable
									.createFromStream(
											mManager.open(mEmojiUtil.getBaseFolder() + "/"
													+ EmojiUtil.EMOJI_CATEGORIES[emojiMaps.category] + "/"
													+ emojiMaps.image), null);
							image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
						}else{
							image = getDrawable(mContext, processEmojiName(emojiMaps.image));
							image.setBounds(0, 0, image.getIntrinsicWidth()*2/3, image.getIntrinsicHeight()*2/3);
						}
						return image;
					} catch (IOException e) {
						e.printStackTrace();
						return mNoImage;
					}
				}
			}
		}
		Log.d(TAG, "CODE: " + code);
		return mNoImage;
	}
	public Drawable getDrawable(String code, int category, boolean isAnimated) {
		if (!isAnimated) return getDrawable(code, category);
		else return getAnimationDrawable(code, category);
	}

	private Drawable getDrawable(String code, int category) {
		for (EmojiMap emojiMaps : mEmojiUtil.getEmojiMaps()[category]) {
			if (code.equals(emojiMaps.code)) {
				if (emojiMaps.image == null || emojiMaps.image.equals(NO_IMAGE)) return mNoImage;
				try {
					Drawable image = Drawable.createFromStream(
							mManager.open(mEmojiUtil.getBaseFolder() + "/"
									+ EmojiUtil.EMOJI_CATEGORIES[emojiMaps.category] + "/" + emojiMaps.image), null);
					image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
					return image;
				} catch (IOException e) {
					e.printStackTrace();
					return mNoImage;
				}
			}
		}
		Log.d(TAG, "CODE: " + code);
		return mNoImage;
	}
	/**
	 * Get drawable from res for emoji
	 * @author binhbt
	 * @param context
	 * @param code
	 * @param category
	 * @return
	 */
	public Drawable getDrawableFromResource(Context context,String code, int category){
		for (EmojiMap emojiMaps : mEmojiUtil.getEmojiMaps()[category]) {
			if (code.equals(emojiMaps.code)) {
				if (emojiMaps.image == null || emojiMaps.image.equals(NO_IMAGE)) return mNoImage;
				try {
					Drawable drawable = getDrawable(context, processEmojiName(emojiMaps.image));
					return drawable;
				} catch (Exception e) {
					e.printStackTrace();
					return mNoImage;
				}
			}
		}
		Log.d(TAG, "CODE: " + code);
		return mNoImage;
	}
	/*
	 * Change file name to correct with real name in drawable(vs map.txt)
	 * @author binhbt
	 * @@-WTF 
	 */
	private String processEmojiName(String name){
		name = name.replace(" ", "");
		name = name.replace("(", "_");
		name = name.replace(")", "");
		//remove extension
		int mid= name.lastIndexOf(".");
		name=name.substring(0,mid);
		
		name = "emoji_"+name;
		return name;
		
	}
	private int getResourceId(Context context, String name){
		String packageName = context.getPackageName();
		int resId = context.getResources().getIdentifier(
			    name, "drawable", packageName);
		return resId;
	}
	private Drawable getDrawable(Context context, String name){
		int resId = getResourceId(context, name);
		return context.getResources().getDrawable(resId);
	}
	public String getName(String code, int category){
		for (EmojiMap emojiMaps : mEmojiUtil.getEmojiMaps()[category]) {
			if (code.equals(emojiMaps.code)) {
				if (emojiMaps.image == null || emojiMaps.image.equals(NO_IMAGE)) return NO_IMAGE;
					return emojiMaps.image;
			}
		}
		Log.d(TAG, "CODE: " + code);
		return NO_IMAGE;
	}
	private Drawable getAnimationDrawable(String code, int category) {
		for (EmojiMap map : mEmojiUtil.getEmojiMaps()[category]) {
			if (code.equals(map.code)) {
				if (map.animationFolder == null) return mNoImage;
				AnimatedDrawable animation = new AnimatedDrawable();
				animation.setOneShot(false);
				int i = 0;
				Drawable frame;
				while (true) {
					try {
						frame = Drawable.createFromStream(
								mManager.open(mEmojiUtil.getBaseFolder() + "/" + map.animationFolder + "/"
										+ map.animationFolder + i + ".png"), null);
						frame.setBounds(0, 0, frame.getIntrinsicWidth(), frame.getIntrinsicHeight());
						animation.addFrame(frame, 100);
						i++;
					} catch (IOException e) {
						break;
					}
				}
				if (i == 0) return mNoImage;
				animation.setBounds(0, 0, animation.getFrame(0).getIntrinsicWidth(), animation.getFrame(0)
						.getIntrinsicHeight());
				return animation;
			}
		}
		return mNoImage;
	}

	public Context getmContext() {
		return mContext;
	}

	public void setmContext(Context mContext) {
		this.mContext = mContext;
	}


}